/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainFrame.java
 *
 * Created on 2011-11-28, 18:12:42
 */
package visual;

import java.util.logging.Level;
import java.util.logging.Logger;
import operators.*;
import genotypes.*;
import geometry.*;
import objectives.*;
import algorithms.*;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import misc.ProblemProfile;

/**
 *
 * @author rusak
 */
public class MainFrame extends javax.swing.JFrame {

    /*
     * Obstacle obstacles[] = new Obstacle[3]; Obstacle hulls[] = new
     * Obstacle[3]; Vertex ob1[] = new Vertex[5]; Vertex ob2[] = new Vertex[11];
     * Vertex ob3[] = new Vertex[10];
     */
    Obstacle obstacles[] = new Obstacle[1];
    Obstacle hulls[] = new Obstacle[1];
    Vertex ob1[] = new Vertex[4];
    Vertex ob2[] = new Vertex[4];
    Vertex ob3[] = new Vertex[4];
    Vertex ob4[] = new Vertex[4];
    Vertex ob5[] = new Vertex[8];
    private double limitations[][] = new double[10][2];
    double lengths[] = new double[7];
    Vertex start = new Vertex(11, 20);
    Vertex dest = new Vertex(11, 17);
    ProblemProfile pp = new ProblemProfile();
    int mapSize;
    double unacceptableSize;
    int rankSelectionFactor1 = 3;
    double rankSelectionFactor2 = 0.4;
    double mutationChance;
    CrossoverOperator cOp;
    MutationOperator mOp;
    SplitOperator sOp;
    SelectionOperator rOp;
    ObjectiveFunction f;
    IDEAStepByStep algorithm;
    IDEADynamic algorithmDynamic;
    ConvexHullAlgorithm cAlg = new GrahamAlgorithm();
    Random r = new Random();
    MutationOperator m1, m2, m3, m4, m5;

    public MainFrame() {

        initComponents();

        cOp = new BetaMutCrossover2();


    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        drawingPanel = new javax.swing.JPanel();
        populationField = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        iterationsField = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        sizeSpinner = new javax.swing.JSpinner();
        jLabel3 = new javax.swing.JLabel();
        nextStepButton = new javax.swing.JButton();
        jPanel1 = new Chart(); chart1 = (Chart)jPanel1;
        jButton3 = new javax.swing.JButton();
        loadField = new javax.swing.JTextField();
        mutationSlider = new javax.swing.JSlider();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        unacceptableSizeSlider = new javax.swing.JSlider();
        jSlider1 = new javax.swing.JSlider();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        jTextField2 = new javax.swing.JTextField();
        jButton4 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jTextField3 = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        drawingPanel.setBackground(new java.awt.Color(255, 255, 255));
        drawingPanel.setPreferredSize(new java.awt.Dimension(638, 518));

        javax.swing.GroupLayout drawingPanelLayout = new javax.swing.GroupLayout(drawingPanel);
        drawingPanel.setLayout(drawingPanelLayout);
        drawingPanelLayout.setHorizontalGroup(
            drawingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 1240, Short.MAX_VALUE)
        );
        drawingPanelLayout.setVerticalGroup(
            drawingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 560, Short.MAX_VALUE)
        );

        populationField.setText("20");

        jLabel1.setText("population size:");

        jLabel2.setText("iterations:");

        iterationsField.setText("20");

        jButton1.setText("start");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        sizeSpinner.setModel(new javax.swing.SpinnerNumberModel(10, 2, 40, 1));
        sizeSpinner.setValue(20);

        jLabel3.setText("map size:");

        nextStepButton.setText("next step");
        nextStepButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextStepButtonActionPerformed(evt);
            }
        });

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 1260, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 118, Short.MAX_VALUE)
        );

        jButton3.setText("load");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        loadField.setText("test7.txt");
        loadField.setToolTipText("");

        jLabel4.setText("mutation chance (%)");

        jLabel5.setText("unacceptable size (%)");

        unacceptableSizeSlider.setValue(20);

        jLabel6.setText("rank factor");

        jLabel7.setText("rank size");

        jTextField1.setText("3");
        jTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });

        jTextField2.setText("0");

        jButton4.setText("Dynamic");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        jButton2.setText("generate");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jButton3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(loadField, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(populationField, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(iterationsField, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(mutationSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, 83, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(unacceptableSizeSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, 149, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(12, 12, 12)
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 57, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(sizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(62, 62, 62)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(nextStepButton, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jTextField2)
                    .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 76, Short.MAX_VALUE))
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(drawingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1240, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(unacceptableSizeSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGroup(layout.createSequentialGroup()
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                        .addComponent(jButton3)
                                        .addComponent(jLabel5)
                                        .addComponent(nextStepButton)
                                        .addComponent(jButton1)
                                        .addComponent(loadField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(jButton2)
                                        .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGap(2, 2, 2)))
                            .addComponent(jLabel6))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jButton4))
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jLabel3)
                                .addComponent(sizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jLabel7)
                                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addComponent(mutationSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(jLabel4)
                                    .addComponent(jLabel2)
                                    .addComponent(iterationsField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(populationField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel1))))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(drawingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private Segment scale(Segment s) {

        Vertex newBegin = scale(s.getBegin());
        Vertex newEnd = scale(s.getEnd());
        Segment scaled = new Segment(newBegin, newEnd);
        return scaled;
    }

    private Vertex scale(Vertex v) {
        mapSize = (Integer) sizeSpinner.getModel().getValue();

        double widthFactor = drawingPanel.getWidth() / mapSize;
        double heightFactor = drawingPanel.getHeight() / mapSize;
        Vertex newV = new Vertex(v.getX() * widthFactor,
                v.getY() * heightFactor);

        return newV;
    }

    private void drawAlgorithmState(AnglesPopulation population, Vertex source, Vertex dest,
            ObjectiveFunction f) {
        Graphics g = drawingPanel.getGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, drawingPanel.getWidth(), drawingPanel.getHeight());
        drawingPanel.validate();
        Vertex scaledSource = scale(source);
        Vertex scaledDest = scale(dest);
        g.setColor(Color.BLACK);
        g.drawOval(new Double(scaledSource.getX()).intValue() - 3,
                new Double(scaledSource.getY()).intValue() - 3, 6, 6);
        g.setColor(Color.RED);
        g.drawOval(new Double(scaledDest.getX()).intValue() - 3,
                new Double(scaledDest.getY()).intValue() - 3, 6, 6);
        int popSize = population.getSize();
        Segment segs[];
        for (int i = 0; i < popSize; i++) {
            segs = f.decode(population.getAnglesAt(i));
            if(population.getAnglesAt(i).isAcceptable()) g.setColor(Color.GREEN);
            else g.setColor(Color.GRAY);
            for (int j = 0; j < segs.length; j++) {
                drawSegment(g, segs[j]);
            }
        }



        for (int i = 0; i < pp.getObstacles().length; i++) {
            drawObstacle(pp.getObstacles()[i], g, Color.RED, false);
            //drawObstacle(hulls[i], g, Color.PINK, true);


        }

        drawingPanel.validate();

    }

    private void drawAlgorithmState(Vertex source, Vertex dest, ObjectiveFunction f) {
        Graphics g = drawingPanel.getGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, drawingPanel.getWidth(), drawingPanel.getHeight());
        drawingPanel.validate();
        Vertex scaledSource = scale(source);
        Vertex scaledDest = scale(dest);
        g.setColor(Color.BLACK);
        g.drawOval(new Double(scaledSource.getX()).intValue() - 3,
                new Double(scaledSource.getY()).intValue() - 3, 6, 6);
        g.setColor(Color.RED);
        g.drawOval(new Double(scaledDest.getX()).intValue() - 3,
                new Double(scaledDest.getY()).intValue() - 3, 6, 6);

        for (int i = 0; i < pp.getObstacles().length; i++) {
            drawObstacle(pp.getObstacles()[i], g, Color.RED, false);
            //drawObstacle(hulls[i], g, Color.PINK, true);


        }

        drawingPanel.validate();

    }

    private void drawObstacle(Obstacle obstacle, Graphics g, Color color, boolean isHull) {
        g.setColor(color);
        int size = obstacle.size();
        Segment edge;
        Segment scaled;
        for (int j = 0; j < size; j++) {
            edge = obstacle.getEdgeAt(j);
            scaled = scale(edge);
            drawSegment(g, edge);
            g.setColor(Color.BLACK);
            /*
             * if (isHull) { g.drawString("EDGE :" + j, (Integer)
             * (scaled.getBegin().getX() + scaled.getEnd().getX()) / 2,
             * (Integer) (scaled.getBegin().getY() + scaled.getEnd().getY()) /
             * 2);
            }
             */
            g.setColor(color);
        }
    }

    private void drawSegment(Graphics g, Segment seg) {
        Segment s = scale(seg);
        g.drawLine(new Double(s.getBegin().getX()).intValue(),
                new Double(s.getBegin().getY()).intValue(),
                new Double(s.getEnd().getX()).intValue(),
                new Double(s.getEnd().getY()).intValue());
        /*if (seg.isObstacle()) {
            g.drawString(seg.getBegin().toString(), new Double(s.getBegin().getX()).intValue(),
                    new Double(s.getBegin().getY()).intValue());
        }*/

    }
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed

        unacceptableSize = new Double(unacceptableSizeSlider.getValue()) / 100.0;
        mutationChance = new Double(mutationSlider.getValue()) / 100.0;
        rankSelectionFactor1 = Integer.parseInt(jTextField1.getText());
        rankSelectionFactor2 = new Double(jSlider1.getValue()) / 100.0;


        m1 = new ExponentialMutation(mutationChance);
        m2 = new ChangeOneAngleMutation(mutationChance);
        m3 = new ChangeFewAnglesMutation(mutationChance);
        // m4 = new TwiceMoreOrLessMutation(mutationChance);
        m5 = new ChangeTwoAnglesMutation(mutationChance);
        double mutationChoice = r.nextDouble();

        if (mutationChoice < 0.25) {
            mOp = m1;
        } else if (mutationChoice < 0.5) {
            mOp = m2;
        } else if (mutationChoice < 0.75) {
            mOp = m3;
        } else {
            mOp = m5;
        }

        rOp = new RankSelection(rankSelectionFactor1, rankSelectionFactor2);
        // mOp = new ExponentialMutation(mutationChance);

        Integer popSize = Integer.parseInt(populationField.getText());
        Integer iterations = Integer.parseInt(iterationsField.getText());
        sOp = new AcceptableSplit(new Double(unacceptableSize * popSize).intValue(), popSize);
        algorithm = new IDEAStepByStep(cOp, mOp, sOp, rOp, f, popSize,
                pp.getLengths().length, new Double(unacceptableSize * popSize).intValue(), pp.getLimitations());
        mapSize = (Integer) sizeSpinner.getModel().getValue();
        drawAlgorithmState(algorithm.getRecentPopulation(), pp.getSource(), pp.getTarget(), f);

        boolean done = false;
        boolean itermode = jTextField2.getText().isEmpty();
        double acceptRange = 0;

        double bestValue = -1;
        double prevBest = -1;
        int stagnationCounter = 0;
        int stagnationLimit = 30;
        if (!itermode) {
            acceptRange = Double.parseDouble(jTextField2.getText());
        }
        int i = 0;

        while (!done) {
            try {
                algorithm.nextStep();
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
                System.out.println("NO I LIPA!");
            }
            if (!itermode) {
                bestValue = algorithm.getBestSoFar().getDistanceToDest();
                if (bestValue != prevBest) {
                    stagnationCounter = 0;
                    prevBest = bestValue;
                } else if (bestValue == prevBest) {
                    stagnationCounter++;


                }
            }
            /*
             * try { //Thread.sleep(1); } catch (InterruptedException ex) {
             * Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE,
             * null, ex);
            }
             */
            drawAlgorithmState(algorithm.getRecentPopulation(), pp.getSource(), pp.getTarget(), f);
            chart1.addRecentResult(algorithm.getBestSoFar().getDistanceToDest());
            chart1.paintComponent(chart1.getGraphics());
            if (itermode && i == iterations) {
                done = true;
            } else if (!itermode && algorithm.getBestSoFar().getDistanceToDest() <= acceptRange) {
                done = true;
                System.out.println("Result found\nDistance from target: " + algorithm.getBestSoFar().getDistanceToDest() + "\n Num. of iterations: " + i);
            }
            i++;

            if (!itermode && stagnationCounter == stagnationLimit) {
                i = 0;
                stagnationCounter = 0;
                algorithm = new IDEAStepByStep(cOp, mOp, sOp, rOp, f, popSize,
                        pp.getLengths().length, new Double(unacceptableSize * popSize).intValue(), pp.getLimitations());

            }
        }


    }//GEN-LAST:event_jButton1ActionPerformed

    private void nextStepButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextStepButtonActionPerformed
        if (algorithm == null) {
            unacceptableSize = new Double(unacceptableSizeSlider.getValue()) / 100.0;
            mutationChance = new Double(mutationSlider.getValue()) / 100.0;
            rankSelectionFactor1 = Integer.parseInt(jTextField1.getText());
            rankSelectionFactor2 = new Double(jSlider1.getValue()) / 100.0;
            rOp = new RankSelection(rankSelectionFactor1, rankSelectionFactor2);
            m1 = new ExponentialMutation(mutationChance);
            m2 = new ChangeOneAngleMutation(mutationChance);
            m3 = new ChangeFewAnglesMutation(mutationChance);
            m4 = new TwiceMoreOrLessMutation(mutationChance);
            m5 = new ChangeTwoAnglesMutation(mutationChance);
            double mutationChoice = r.nextDouble();

            if (mutationChoice < 0.2) {
                mOp = m1;
            } else if (mutationChoice < 0.4) {
                mOp = m2;
            } else if (mutationChoice < 0.6) {
                mOp = m3;
            } else if (mutationChoice < 0.8) {
                mOp = m4;
            } else {
                mOp = m5;
            }
            // mOp = new ExponentialMutation(mutationChance);

            Integer popSize = Integer.parseInt(populationField.getText());
            sOp = new AcceptableSplit(new Double(unacceptableSize * popSize).intValue(), popSize);
            algorithm = new IDEAStepByStep(cOp, mOp, sOp, rOp, f, popSize,
                    pp.getLengths().length, new Double(unacceptableSize * popSize).intValue(), pp.getLimitations());

        }
        try {
            algorithm.nextStep();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            System.out.println("NO I LIPA!");

        }
        Angles best = algorithm.getBestSoFar();
        System.out.println(best.getDistanceToDest());
        Segment bestEfector[] = f.decode(best);
        System.out.println("AT POINT: " + bestEfector[best.getAngles().length - 1].getEnd());
        drawAlgorithmState(algorithm.getRecentPopulation(), pp.getSource(), pp.getTarget(), f);
        chart1.addRecentResult(algorithm.getBestSoFar().getDistanceToDest());
        //drawingPanel.repaint();
    }//GEN-LAST:event_nextStepButtonActionPerformed

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        String fileName = loadField.getText();
        pp.loadFromFile("data/" + fileName);
        f = new ConvexHullObjective(pp, new SimpleIntersectionAlgorithm(), new GrahamAlgorithm());
        algorithm = null;
        drawAlgorithmState(pp.getSource(), pp.getTarget(), f);
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jTextField1ActionPerformed

    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
        unacceptableSize = new Double(unacceptableSizeSlider.getValue()) / 100.0;
        mutationChance = new Double(mutationSlider.getValue()) / 100.0;
        rankSelectionFactor1 = Integer.parseInt(jTextField1.getText());
        rankSelectionFactor2 = new Double(jSlider1.getValue()) / 100.0;


        m1 = new ExponentialMutation(mutationChance);
        m2 = new ChangeOneAngleMutation(mutationChance);
        m3 = new ChangeFewAnglesMutation(mutationChance);
        // m4 = new TwiceMoreOrLessMutation(mutationChance);
        m5 = new ChangeTwoAnglesMutation(mutationChance);
        double mutationChoice = r.nextDouble();

        if (mutationChoice < 0.25) {
            mOp = m1;
        } else if (mutationChoice < 0.5) {
            mOp = m2;
        } else if (mutationChoice < 0.75) {
            mOp = m3;
        } else {
            mOp = m5;
        }

        rOp = new RankSelection(rankSelectionFactor1, rankSelectionFactor2);
        // mOp = new ExponentialMutation(mutationChance);

        Integer popSize = Integer.parseInt(populationField.getText());
        Integer iterations = Integer.parseInt(iterationsField.getText());
        sOp = new AcceptableSplit(new Double(unacceptableSize * popSize).intValue(), popSize);
        algorithmDynamic = new IDEADynamic(cOp, mOp, sOp, rOp, f, popSize,
                pp.getLengths().length, new Double(unacceptableSize * popSize).intValue(), pp.getLimitations());

        algorithmDynamic.injectSharedObjectiveFunctionAndChangedFlag(f, Boolean.FALSE);
        mapSize = (Integer) sizeSpinner.getModel().getValue();
        drawAlgorithmState(algorithmDynamic.getRecentPopulation(), pp.getSource(), pp.getTarget(), f);

        boolean done = false;
        boolean itermode = jTextField2.getText().isEmpty();
        double acceptRange = 0;

        int changeTime = pp.getIterToChange();
        int changeCounter = 0;
        if (!itermode) {
            acceptRange = Double.parseDouble(jTextField2.getText());
        }
        int i = 0;
        //hardcoded
        //  String fileName2 = "data/test7b.txt";
        ProblemProfile pp2 = new ProblemProfile();
        // pp2.loadFromFile(fileName2);
        // boolean cycle = true;
        
        String curr_dir = "data/";
        if(loadField.getText().contains("/")) {
            curr_dir += loadField.getText().substring(0,loadField.getText().lastIndexOf("/")+1);
        }
        System.out.println(curr_dir);
        while (!done) {

            if (changeCounter == changeTime) {
                
                System.out.println("CHANGE TO: " + pp.getNextFileName());
                pp2.loadFromFile(curr_dir + pp.getNextFileName());
                pp = pp2;
                changeTime = pp.getIterToChange();

                f = new ConvexHullObjective(pp2, new SimpleIntersectionAlgorithm(), new GrahamAlgorithm());
                changeCounter = 1;
                algorithmDynamic.injectSharedObjectiveFunctionAndChangedFlag(f, Boolean.TRUE);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ex) {
                    Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {
                changeCounter++;
                System.out.println("WITHOUT CHANGE");
            }
            try {
                algorithmDynamic.nextStep();
            } catch (Exception ex) {

                System.out.println(ex.getMessage());
                System.out.println("NO I LIPA!");
            }
            algorithmDynamic.injectSharedObjectiveFunctionAndChangedFlag(f, Boolean.FALSE);

            /*
             * try { //Thread.sleep(1); } catch (InterruptedException ex) {
             * Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE,
             * null, ex);
            }
             */
            drawAlgorithmState(algorithmDynamic.getRecentPopulation(), pp.getSource(), pp.getTarget(), f);
            chart1.addRecentResult(algorithmDynamic.getBestSoFar().getDistanceToDest());
            chart1.paintComponent(chart1.getGraphics());
            if (itermode && i == iterations) {
                done = true;
            } else if (!itermode && algorithmDynamic.getBestSoFar().getDistanceToDest() <= acceptRange) {
                done = true;
                System.out.println("Result found\nDistance from target: "
                        + algorithmDynamic.getBestSoFar().getDistanceToDest() + "\n Num. of iterations: " + i);
            }
            i++;


        }
    }//GEN-LAST:event_jButton4ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        pp.generateNext(pp.getNextFileName(), Integer.parseInt(jTextField3.getText()));
    }//GEN-LAST:event_jButton2ActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new MainFrame().setVisible(true);
            }
        });
    }
    private Chart chart1;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel drawingPanel;
    private javax.swing.JTextField iterationsField;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JSlider jSlider1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    private javax.swing.JTextField loadField;
    private javax.swing.JSlider mutationSlider;
    private javax.swing.JButton nextStepButton;
    private javax.swing.JTextField populationField;
    private javax.swing.JSpinner sizeSpinner;
    private javax.swing.JSlider unacceptableSizeSlider;
    // End of variables declaration//GEN-END:variables
}
